package com.leyou.comment.service;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.leyou.comment.config.JwtProperties;
import com.leyou.comment.repository.CommentRepository;
import com.leyou.common.auth.JwtUtils;
import com.leyou.common.auth.pojo.Payload;
import com.leyou.common.auth.pojo.UserInfo;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.pojo.PageResult;
import com.leyou.common.utils.CookieUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import com.leyou.comment.pojo.Comment;
import com.leyou.comment.pojo.CommentChild;

import java.util.*;


@Service
public class CommentService {
    @Autowired
    private CommentRepository commentRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private JwtProperties jwtProperties;

    //分页查询spu评价
    public PageResult<Comment> findBySpuId(Integer num, Integer size, Long spuId, String score) {
        Query query = null;
        PageResult<Comment> pageResult = new PageResult<>();
        Criteria criteria = Criteria.where("spuId").is(spuId);
        if (!StringUtils.isEmpty(score)) {
            if (score.equals("0")) {
                criteria.and("images").exists(true);  //带晒图
            }
            if (score.equals("1")) {
                criteria.and("score").gte(4).lte(5);  //好评
            }
            if (score.equals("2")) {
                criteria.and("score").is(3);         //中评
            }
            if (score.equals("3")) {
                criteria.and("score").lte(2).gte(0); //差评
            }
        }
        query = new Query(criteria);
        Pageable pageable = PageRequest.of(num - 1, size);
        List<Comment> comments = mongoTemplate.find(query.with(pageable), Comment.class);
        long count = mongoTemplate.count(query, Comment.class);
        //封装至PageResult;
        pageResult.setItems(comments);
        pageResult.setTotal(count);
        pageResult.setTotalPage((count + size - 1) / size);
        return pageResult;
    }

    //分页查询sku评价
    public PageResult<Comment> findBySkuId(Integer num, Integer size, Long skuId, String score) {
        Query query = null;
        PageResult<Comment> pageResult = new PageResult<>();
        Criteria criteria = Criteria.where("skuId").is(skuId);
        if (!StringUtils.isEmpty(score)) {
            if (score.equals("0")) {
                criteria.and("images").exists(true);  //带晒图
            }
            if (score.equals("1")) {
                criteria.and("score").gte(4).lte(5);  //好评
            }
            if (score.equals("2")) {
                criteria.and("score").is(3); //中评
            }
            if (score.equals("3")) {
                criteria.and("score").lte(2).gte(0); //差评
            }
        }
        query = new Query(criteria);
        Pageable pageable = PageRequest.of(num - 1, size);
        List<Comment> comments = mongoTemplate.find(query.with(pageable), Comment.class);
        long count = mongoTemplate.count(query, Comment.class);
        //封装至PageResult;
        pageResult.setItems(comments);
        pageResult.setTotal(count);
        pageResult.setTotalPage((count + size - 1) / size);
        return pageResult;
    }

    //添加数据
    public void save(Comment comment) {
        commentRepository.save(comment);
    }

    //修改点赞数
    public void updateLikeNum(Long id, Integer likeNum) {
        Query query = new Query(Criteria.where("commentId").is(id));
        Update update = new Update();
        update.set("likeNum", likeNum + 1);
        mongoTemplate.updateFirst(query, update, Comment.class);
    }

    //追加评论
    public void updateAddContent(Long id, String addContent) {
        Comment comment = mongoTemplate.findById(id, Comment.class);
        if (comment.getAddCount() > 0) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        Query query = new Query(Criteria.where("commentId").is(id));
        Update update = new Update();
        update.set("addContent", addContent);
        update.set("addCount", 1);
        update.set("addTime", new Date());
        mongoTemplate.updateFirst(query, update, Comment.class);
    }

    //回复评论
    public void updateReplyComment(Long id, String content, HttpServletRequest request) {
        UserInfo user = getUser(request);
        Comment comment = mongoTemplate.findById(id, Comment.class);
        Map<Long, CommentChild> commentChildren = comment.getCommentChildren();
        //封装子评论
        Long childId = Long.valueOf(RandomStringUtils.randomNumeric(10));
        CommentChild commentChild = new CommentChild();
        commentChild.setParentId(id);
        commentChild.setChildId(childId);
        commentChild.setContent(content);
        commentChild.setUserId(user.getId());
        commentChild.setUserName(user.getUsername());
        commentChild.setCreateTime(new Date());
        //添加至子评论集合
        if (CollectionUtils.isEmpty(commentChildren)) {
            commentChildren = new LinkedHashMap<>();
        }
        commentChildren.put(childId, commentChild);
        Query query = new Query(Criteria.where("commentId").is(id));
        Update update = new Update();
        update.set("commentChildren", commentChildren);
        mongoTemplate.updateFirst(query, update, Comment.class);
    }

    public UserInfo getUser(HttpServletRequest request) {
        //校验用户
        Payload<UserInfo> userInfoPayload = null;
        try {
            String userToken = CookieUtils.getCookieValue(request, jwtProperties.getCookie().getCookieName());
            userInfoPayload = JwtUtils.getInfoFromToken(userToken, jwtProperties.getPublicKey(), UserInfo.class);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UNAUTHORIZED);
        }
        return userInfoPayload.getInfo();
    }

    //子评论下的回复
    public void childReply(Long commentId, Long childId, String replyContent, HttpServletRequest request,String replyChildName) {
        UserInfo user = getUser(request);
        Comment comment = mongoTemplate.findById(commentId, Comment.class);
        //取出子评论集合
        Map<Long, CommentChild> commentChildMap = comment.getCommentChildren();
        if (CollectionUtils.isEmpty(commentChildMap)) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        //取出子评论下的评论集合
        CommentChild commentChild = commentChildMap.get(childId);
        Map<Long, CommentChild> commentChildMapX = commentChild.getCommentChildrenX();
        if (CollectionUtils.isEmpty(commentChildMapX)) {
            commentChildMapX = new LinkedHashMap<>();
        }
        //封装子评论下的评论信息
        Long childIdX = Long.valueOf(RandomStringUtils.randomNumeric(10));
        CommentChild commentChildX = new CommentChild();
        commentChildX.setParentId(childId);
        commentChildX.setChildId(childIdX);
        commentChildX.setUserId(user.getId());
        commentChildX.setUserName(user.getUsername());
        commentChildX.setContent(replyContent);
        commentChildX.setReplyName(replyChildName);
        commentChildX.setCreateTime(new Date());
        //set回原本数据体
        commentChildMapX.put(childIdX, commentChildX);
        commentChild.setCommentChildrenX(commentChildMapX);
        commentChildMap.put(childId, commentChild);

        //更新数据
        Query query = new Query(Criteria.where("commentId").is(commentId));
        Update update = new Update();
        update.set("commentChildren", commentChildMap);
        mongoTemplate.updateFirst(query, update, Comment.class);
    }
}
